/***************************************************************
*  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
*  All rights reserved.
*
*  This file is part of the GroupMe! Project. Source code of 
*  this project is closed and redistribution of this code is
*  prohibited. 
*  
*  Contact: http://www.groupme.net
*
*  This copyright notice MUST APPEAR in all copies of the file!
***************************************************************/
package net.groupme.search.strategy.folkrank;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import net.groupme.model.ObjectFactory;
import net.groupme.search.strategy.model.TAS;
import net.groupme.search.strategy.model.TASImpl;
import cern.colt.matrix.impl.SparseDoubleMatrix2D;

/**
 * created on 15 Jan 2008
 * 
  * This class extends the traditional FolkRank ranking strategy by using groups 
 * as artificial tags and by propagating group tags to resources.
 * 
 * @author Fabian Abel, <a href="mailto:abel@l3s.de">abel@l3s.de</a>
 * @author last edited by: $Author: fabian $
 * 
 * @version $Revision: 1.2 $ $Date: 2008-01-17 02:58:58 $
 */
public class FolkRankWithGroupsAsArtificialTagsAndGroupTagInheritage extends FolkRankWithGroupsAsArtificialTags{
	
	/**
	 * Creates a new FolkRankWithGroupsAsArtificialTags instance. 
	 */
	public FolkRankWithGroupsAsArtificialTagsAndGroupTagInheritage() {
		super();
	}

	/* (non-Javadoc)
	 * @see net.groupme.search.strategy.folkrank.NormalFolkRankRankingStrategy#getName()
	 */
	@Override
	public String getName() {
		return "Groups as Tags + GTPropagation";
	}

	/* (non-Javadoc)
	 * @see net.groupme.search.strategy.folkrank.NormalFolkRankRankingStrategy#getDescription()
	 */
	@Override
	public String getDescription() {
		return "Groups are treated as artifical tags and assigned to contained resources, tags of a group are propagated to contained resources and afterwards normal FolkRank";
	}
	
	/* (non-Javadoc)
	 * @see net.groupme.search.strategy.folkrank.NormalFolkRankRankingStrategy#constructAdjacencyMatrix()
	 */
	@Override
	protected void constructAdjacencyMatrix(){
		/* 1. Gather data: */
		Statement sqlStatement = null;
		ResultSet result = null;
		List<TAS> tagAssignments = null;
		
		try {
			sqlStatement = ObjectFactory.ds.getConnection().createStatement();
		
			//get TAS and define mappings: 
			tagAssignments = addNormalMappings(sqlStatement);
			
			//propagate group tags 
			result = sqlStatement.executeQuery("Select a.userId, a.tagId, b.resourceId, a.resourceId from userTagGroupResource as a, groupResource as b where a.resourceId = b.groupId AND a.groupId is NULL ");
			TAS actualTas = null;
			while(result.next()){
				actualTas = new TASImpl(result.getInt(1), result.getInt(2),result.getInt(3),result.getInt(4));
				actualTas.setDirectTAS(false);
				tagAssignments.add(actualTas);	
				//nur (ungetaggte) resourcen koennen dazukommen 
				if(!resourceIdColumMapping.containsKey(actualTas.getResourceId())){
					resourceIdColumMapping.put(actualTas.getResourceId(), position);
					position++;
				}
			}
			//create artificial tags:
			result = sqlStatement.executeQuery("SELECT DISTINCT groupId FROM groupResource"); // where groupId in (Select distinct groupId from userTagGroupResource " + specificUserSql + ")");
			String artificialId = null;
			while(result.next()){
				artificialId = result.getInt(1) + ARTIFICIAL_GROUP_TAG_SUFFIX;
				artificialTagIdColumMapping.put(artificialId, position);
				position++;
			}
		
		
			/* 2. Compute the Matrix: */
			
			//construct Matrix
			int numberOfVertices = userIdColumMapping.size() + tagIdColumMapping.size() + resourceIdColumMapping.size() + artificialTagIdColumMapping.size();
			adjacencyMatrix = new SparseDoubleMatrix2D(numberOfVertices,numberOfVertices);
			
			//fill adjacency matrix
			fillMatrixWithNormalTagAssignments(tagAssignments);
			
			//row-wise 1-Norm:
			computeRowWiseThe1Norm();
		}catch (SQLException e) {
			e.printStackTrace();
		}
		
	}
}
